package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.model.enums.ItemType;
import com.atguigu.lease.model.enums.ReleaseStatus;
import com.atguigu.lease.web.admin.mapper.*;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.attr.AttrValueVo;
import com.atguigu.lease.web.admin.vo.graph.GraphVo;
import com.atguigu.lease.web.admin.vo.room.RoomDetailVo;
import com.atguigu.lease.web.admin.vo.room.RoomItemVo;
import com.atguigu.lease.web.admin.vo.room.RoomQueryVo;
import com.atguigu.lease.web.admin.vo.room.RoomSubmitVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author liubo
 * @description 针对表【room_info(房间信息表)】的数据库操作Service实现
 * @createDate 2023-07-24 15:48:00
 */
@Service
public class RoomInfoServiceImpl extends ServiceImpl<RoomInfoMapper, RoomInfo>
        implements RoomInfoService {
    @Autowired
    private GraphInfoMapper graphInfoMapper;
    @Autowired
    private LeaseTermMapper leaseTermMapper;
    @Autowired
    private PaymentTypeMapper paymentTypeMapper;
    @Autowired
    private RoomInfoMapper roomInfoMapper;
    @Autowired
    private GraphInfoService graphInfoService;
    @Autowired
    private RoomAttrValueService roomAttrValueService;
    @Autowired
    private RoomFacilityService roomFacilityService;
    @Autowired
    private RoomLabelService roomLabelService;
    @Autowired
    private RoomPaymentTypeService roomPaymentTypeService;
    @Autowired
    private RoomLeaseTermService roomLeaseTermService;
    @Autowired
    private ApartmentInfoService apartmentInfoService;
    @Autowired
    private AttrValueMapper attrValueMapper;
    @Autowired
    private FacilityInfoMapper facilityInfoMapper;
    @Autowired
    private LabelInfoMapper labelInfoMapper;


    @Override
    public int updateReleaseStatusById(Long id, ReleaseStatus status) {
        LambdaUpdateWrapper<RoomInfo> roomInfoLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        roomInfoLambdaUpdateWrapper.set(RoomInfo::getIsRelease, status.getCode());
        roomInfoLambdaUpdateWrapper.eq(RoomInfo::getId, id);
        return roomInfoMapper.update(null, roomInfoLambdaUpdateWrapper);
    }

    @Override
    @Transactional
    public void saveOrUpdateRoomInfo(RoomSubmitVo roomSubmitVo) {

        boolean isUpdate = roomSubmitVo.getId() != null;
        // 保存/更新 room_info
        saveOrUpdate(roomSubmitVo);
        if (isUpdate) {
            // 删除关联表的数据
            graphInfoService.remove(Wrappers.lambdaQuery(GraphInfo.class)
                    .eq(GraphInfo::getItemId,roomSubmitVo.getId())
                    .eq(GraphInfo::getItemType,ItemType.ROOM));
            roomAttrValueService.remove(Wrappers.lambdaQuery(RoomAttrValue.class).eq(RoomAttrValue::getRoomId,roomSubmitVo.getId()));
            roomFacilityService.remove(Wrappers.lambdaQuery(RoomFacility.class).eq(RoomFacility::getRoomId,roomSubmitVo.getId()));
            roomLabelService.remove(Wrappers.lambdaQuery(RoomLabel.class).eq(RoomLabel::getRoomId,roomSubmitVo.getId()));
            roomPaymentTypeService.remove(Wrappers.lambdaQuery(RoomPaymentType.class).eq(RoomPaymentType::getRoomId,roomSubmitVo.getId()));
            roomLeaseTermService.remove(Wrappers.lambdaQuery(RoomLeaseTerm.class).eq(RoomLeaseTerm::getRoomId,roomSubmitVo.getId()));
        }

        // 保存/更新 graph_info
        List<GraphInfo> graphInfos = roomSubmitVo.getGraphVoList().stream().map(graphVo -> {
            GraphInfo graphInfo = new GraphInfo();
            graphInfo.setUrl(graphVo.getUrl());
            graphInfo.setName(graphVo.getName());
            return graphInfo;
        }).collect(Collectors.toList());
        graphInfoService.saveOrUpdateBatch(graphInfos);
        // 保存/更新 room_attr_value
        List<RoomAttrValue> roomAttrValues = roomSubmitVo.getAttrValueIds().stream().map(attrValueId ->
                RoomAttrValue.builder()
                        .attrValueId(attrValueId)
                        .roomId(roomSubmitVo.getId())
                        .build()
        ).collect(Collectors.toList());
        roomAttrValueService.saveOrUpdateBatch(roomAttrValues);
        // 保存/更新 room_facility
        List<RoomFacility> roomFacilities = roomSubmitVo.getFacilityInfoIds().stream().map(facilityInfoId ->
                RoomFacility.builder()
                        .roomId(roomSubmitVo.getId())
                        .facilityId(facilityInfoId)
                        .build()
        ).collect(Collectors.toList());
        roomFacilityService.saveOrUpdateBatch(roomFacilities);
        // 保存/更新 room_label
        List<RoomLabel> roomLabels = roomSubmitVo.getLabelInfoIds().stream().map(labelInfoId ->
                RoomLabel.builder()
                        .roomId(roomSubmitVo.getId())
                        .labelId(labelInfoId)
                        .build()
        ).collect(Collectors.toList());
        roomLabelService.saveOrUpdateBatch(roomLabels);
        // 保存/更新 room_payment_type
        List<RoomPaymentType> roomPaymentTypes = roomSubmitVo.getPaymentTypeIds().stream().map(paymentTypeId ->
                RoomPaymentType.builder()
                        .roomId(roomSubmitVo.getId())
                        .paymentTypeId(paymentTypeId)
                        .build()
        ).collect(Collectors.toList());
        roomPaymentTypeService.saveOrUpdateBatch(roomPaymentTypes);
        // 保存/更新 room_lease_term
        List<RoomLeaseTerm> roomLeaseTerms = roomSubmitVo.getLeaseTermIds().stream().map(leaseTerms ->
                RoomLeaseTerm.builder()
                        .roomId(roomSubmitVo.getId())
                        .leaseTermId(leaseTerms)
                        .build()
        ).collect(Collectors.toList());
        roomLeaseTermService.saveOrUpdateBatch(roomLeaseTerms);
    }

    @Override
    public IPage<RoomItemVo> getPageItem(IPage<RoomItemVo> page, RoomQueryVo queryVo) {
        return roomInfoMapper.getPageItem(page,queryVo);
    }

    @Override
    public RoomDetailVo getDetailById(Long id) {
        // 查询 room_info
        RoomInfo roomInfo = getById(id);
        // 查询 apartment_info
        ApartmentInfo apartmentInfo = apartmentInfoService.getById(roomInfo.getApartmentId());
        // 查询 graph_info
        List<GraphVo> graphVoList = graphInfoMapper.getGraphVoListByRoomIdAndType(id,ItemType.ROOM.getCode());
        // 查询 attr_value
        List<AttrValueVo> attrValueVoList = attrValueMapper.getAttrValueVoListByRoomId(id);
        // 查询 facility_info
        List<FacilityInfo> facilityInfos = facilityInfoMapper.getFacilityInfoListByRoomId(id);
        // 查询 label_info
        List<LabelInfo> labelInfos = labelInfoMapper.getLabelInfoListByRoomId(id);
        // 查询 payment_type
        List<PaymentType> paymentTypes = paymentTypeMapper.getPaymentTypeListByRoomId(id);
        // 查询 lease_term
        List<LeaseTerm> leaseTerms = leaseTermMapper.getLeaseTermListByRoomId(id);

        RoomDetailVo result = new RoomDetailVo();
        BeanUtils.copyProperties(roomInfo,result);
        result.setApartmentInfo(apartmentInfo);
        result.setGraphVoList(graphVoList);
        result.setAttrValueVoList(attrValueVoList);
        result.setFacilityInfoList(facilityInfos);
        result.setLabelInfoList(labelInfos);
        result.setPaymentTypeList(paymentTypes);
        result.setLeaseTermList(leaseTerms);
        return result;
    }
}




